﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using System.Web.Mvc;
using System.IO;

namespace Steve.UI
{
    public class TextContentDataHandlerModel
    {
        public string Text { get; set; }
        public Content Content { get; set; }
    }

    public class TextContentDataHandlerEditModel : TextContentDataHandlerModel
    {
        public string InputName { get; set; }
    }

    [Export(typeof(ContentDataHandlerBase))]
    [ExportMetadata("Name", "Plain")]
    public class TextContentDataHandler : ContentDataHandlerBase
    {
        const string ViewNameKey = "ViewName";
        const string MasterNameKey = "MasterName";

        protected string InputName { get; set; }
        protected string DefaultEditViewName { get; set; }
        protected MimeType MimeType { get; set; }
        protected string MimeSubtype { get; set; }

        public TextContentDataHandler()
        {
            InputName = "text-plain-content-data";
            DefaultEditViewName = "TextPlainEdit";
            MimeType = MimeType.Text;
            MimeSubtype = "plain";
        }

        [Import]
        public IHttpContextBaseBuilder ContextBuilder { get; set; }
        [Import]
        public ContentRepository ContentRepository { get; set; }

        protected internal virtual string GetText(Stream stream)
        {
            string text;

            using (var sr = new StreamReader(stream, Encoding.UTF8))
            {
                text = sr.ReadToEnd();
            }

            return text;
        }

        public override ActionResult Render(Content content, ContentType contentType, bool raw)
        {
            if (content == null) throw new ArgumentNullException("content");
            if (contentType == null) throw new ArgumentNullException("contentType");

            var viewName = contentType.Parameters != null && contentType.Parameters.ContainsKey(ViewNameKey) ? contentType.Parameters[ViewNameKey] : contentType.ContentTypeName;
            var masterName = contentType.Parameters != null && contentType.Parameters.ContainsKey(MasterNameKey) ? contentType.Parameters[MasterNameKey] : contentType.ContentTypeName;
            var stream = ContentRepository.GetContentData(content.ContentDataId.Value);
            var text = GetText(stream);

            if (raw)
            {
                return new FileContentResult(Encoding.UTF8.GetBytes(text), content.FullMimeType + "; charset=utf-8");
            }

            var result = new ViewResult();

            result.MasterName = masterName;
            result.ViewName = viewName;
            result.ViewData = new ViewDataDictionary();
            result.ViewData.Model = new TextContentDataHandlerModel()
            {
                Content = content,
                Text = text
            };

            return result;
        }

        public override ActionResult Edit(Content content, ContentType contentType)
        {
            if (content == null) throw new ArgumentNullException("content");
            if (contentType == null) throw new ArgumentNullException("contentType");

            var viewName = contentType.Parameters != null && contentType.Parameters.ContainsKey(ViewNameKey) ? contentType.Parameters[ViewNameKey] : DefaultEditViewName;

            var result = new PartialViewResult();

            result.ViewName = viewName;

            using (var sr = new StreamReader(ContentRepository.GetContentData(content.ContentDataId.Value), Encoding.UTF8))
            {
                var text = sr.ReadToEnd();

                result.ViewData.Model = new TextContentDataHandlerEditModel()
                {
                    Content = content,
                    Text = text,
                    InputName = InputName
                };
            }

            return result;
        }

        protected override ContentDataHandlerEditData GetEditData(ContentType contentType)
        {
            var ctx = ContextBuilder.BuildCurrent();
            var html = ctx.Request.Form[InputName];
            var bytes = Encoding.UTF8.GetBytes(html);

            return new ContentDataHandlerEditData()
            {
                MimeType = MimeType,
                MimeSubtype = MimeSubtype,
                Data = new MemoryStream(bytes)
            };
        }

        public override string ExtractText(Content content, ContentType contentType)
        {
            if (content == null) throw new ArgumentNullException("content");
            if (contentType == null) throw new ArgumentNullException("contentType");

            var stream = ContentRepository.GetContentData(content.ContentDataId.Value);
            var text = GetText(stream);

            return text;
        }
    }
}
